<template>
  <div class="app-container">
    <van-field v-model="item.value" :class="item.class" :type="item.colType" :label="item.label" :border="true" :placeholder="placeholder" :disabled="item.disabled" @blur="onBlur">
      <template #button>
        <van-button size="small" type="info" class="btn-cls" @click="showORCDialog">
          拍照自动识别
        </van-button>
      </template>
    </van-field>
    <van-popup v-model="showPop" style="width:100%;height:100%">
      <van-nav-bar title="身份证识别" left-text="" right-text="确定" left-arrow @click-left="onClickLeft" @click-right="onClickRight" />
      <div class="container">
        <van-row>
          <van-col span="12">
            <p>身份证人像面</p>
            <van-image :src="faceSide" style="width:98%; margin-bottom:10px;" height="100" @click="faceImagePerview(faceSide)" />
            <div>
              <van-uploader :after-read="afterReadFaceSide" accept="image/*">
                <van-button type="info" size="small" block>拍照片</van-button>
              </van-uploader>
            </div>
          </van-col>
          <van-col span="12">
            <p>身份证国徽面</p>
            <van-image :src="backSide" style="width:98%;  margin-bottom:10px;" height="100" @click="faceImagePerview(backSide)" />
            <div>
              <van-uploader :after-read="afterReadBackSide" accept="image/*">
                <van-button type="info" size="small" block>拍照片</van-button>
              </van-uploader>
            </div>
          </van-col>
        </van-row>
      </div>
      <div class="container">
        <van-field v-model="idCardData.name" label="姓   名" />
        <van-field v-model="idCardData.sex" label="性   别" />
        <van-field v-model="idCardData.nationality" label="民   族" />
        <van-field v-model="idCardData.birth" label="出生年月" />
        <van-field v-model="idCardData.address" label="住   址" />
        <van-field v-model="idCardData.num" label="身份证号" />
      </div>
      <div class="container">
        <van-field v-model="idCardData.issue" label="签发机关" />
        <van-field v-model="idCardData.startDate" label="有效期起始" />
        <van-field v-model="idCardData.endDate" label="有效期结束" />
      </div>
    </van-popup>
  </div>
</template>

<script>
import EXIF from 'exif-js'
import EleBase from './EleBase'
import { Toast } from 'vant'
import axios from 'axios'
// import { allResolved } from 'q'
import { ImagePreview } from 'vant'

import 'vant/es/toast/style'

export default {
  name: 'EleIDCardOCR',
  extends: EleBase,
  props: {
    item: {
      type: Object, // 类型
      default: null // 默认值
    },
    accept: {
      type: String,
      default: 'image/*'
    },
    maxcount: {
      type: Number,
      default: 1
    },
    side: {
      type: String,
      default: 'face'
    }
  },
  data() {
    return {
      showPop: false,
      result: null,
      viewUrl: 'view/compress',
      uploadUrl: 'api/Files/orc/idcard',
      faceSideFile: Object,
      faceSide: require('../../../assets/images/idcard1.png'),
      backSideFile: Object,
      backSide: require('../../../assets/images/idcard2.png'),
      idCardData: {
        name: '',
        address: '',
        nationality: '',
        num: '',
        sex: '',
        birth: '',
        faceImage: '',
        issue: '',
        startDate: '',
        endDate: '',
        faceImg: '',
        backImg: ''
      }
    }
  },
  computed: {
    errMsg() {
      let str = ''
      if (this.item.required) {
        if (this.item.undermsg === '') {
          str = '请选择' + this.item.label
        } else {
          str = this.item.undermsg
        }
      }
      return str
    },
    placeholder() {
      let str = ''
      if (this.item.placeholder) {
        str = this.item.placeholder
      } else if (this.item.label) {
        str = '请输入' + this.item.label
      }
      return str
    }
  },
  methods: {
    faceImagePerview(image) {
      ImagePreview({
        images: [image],
        showIndex: true,
        loop: false,
        startPosition: 0
      })
    },
    onClickLeft() {
      this.showPop = false
    },
    onClickRight() {
      try {
        const linkFields = this.item.linkFields
        this.$emit('idCardORCCallback', { field: JSON.parse(linkFields), value: this.idCardData })
      } catch (e) {
        this.$notify({
          type: 'warning',
          message: e.message
        })
      }
      this.showPop = false
    },
    onBlur() {

    },
    showORCDialog() {
      console.log('showORCDialog')
      this.showPop = true
    },
    afterReadFaceSide(inFile) {
      var _this = this
      var file = inFile.file
      if (file.type !== 'image/jpeg') {
        Toast('请上传 jpg 格式图片')
        return false
      }
      // console.log('file.content=' + file.content)
      // this.faceSide = file.content
      _this.faceSideSour = inFile
      _this.fileobj_change(inFile)
      debugger
      _this.watermark({
        url: inFile.content, // 这里传的file是上传的图片文件
        content: '仅供 合协软件公司 入职使用', // 仅供入职使用
        cb: base64Url => {
          // console.log(base64Url) // 转换完成的base64格式图片
          _this.faceSide = base64Url
          _this.uploadImgs(inFile, 0)
        }
      })
      return true
    },
    afterReadBackSide(inFile) {
      var _this = this
      var file = inFile.file
      if (file.type !== 'image/jpeg') {
        Toast('请上传 jpg 格式图片')
        return false
      }
      // console.log('file.content=' + file.content)
      // this.faceSide = file.content
      _this.backSideSour = inFile
      _this.fileobj_change(inFile)
      _this.watermark({
        url: inFile.content, // 这里传的file是上传的图片文件
        content: '仅供 合协软件公司 入职使用', //
        cb: base64Url => {
          // console.log(base64Url) // 转换完成的base64格式图片
          _this.backSide = base64Url
          _this.uploadImgs(inFile, 1)
        }
      })
      return true
    },
    // 返回 Promise
    asyncBeforeRead(file) {
      return new Promise((resolve, reject) => {
        if (file.type !== 'image/jpg') {
          Toast('请上传 jpg 格式图片')
          reject()
        } else {
          var img = new File(['foo'], 'bar.jpg', {
            type: 'image/jpeg'
          })
          resolve(img)
        }
      })
    },
    // 上传的图片加水印
    watermark({
      url = '',
      textAlign = 'left',
      textBaseline = 'top',
      font = '28px Microsoft Yahei',
      fillStyle = 'rgba(255, 0, 0, 1)',
      content = '仅供 合协软件公司 入职使用',
      cb = null
    } = {}) {
      const img = new Image()
      img.src = url
      img.crossOrigin = 'anonymous'
      img.onload = function () {
        const canvas = document.createElement('canvas')
        var _ix = img.width
        var _iy = img.height
        canvas.width = _ix
        canvas.height = _iy
        const ctx = canvas.getContext('2d')
        ctx.drawImage(img, 0, 0)
        ctx.textAlign = textAlign
        ctx.textBaseline = textBaseline
        ctx.font = font
        ctx.fillStyle = fillStyle
        ctx.translate(0, 0)
        ctx.rotate((Math.PI / 180) * 30) // 旋转
        // 水印密度
        ctx.fillText(content, 50, 10, _ix)
        /* for (let i = 0; i < _iy / 120; i++) {
          for (let j = 0; j < _ix / 50; j++) {
            ctx.fillText(content, i * 120, j * 50, _ix)
          }
        } */
        const base64Url = canvas.toDataURL()
        cb && cb(base64Url)
      }
    },
    // 上传
    uploadImgs(file, side) {
      var _this = this
      debugger
      const formData = new FormData()
      const toast = Toast.loading({
        message: '图像识别中...',
        forbidClick: true,
        loadingType: 'spinner'
      })
      formData.append('file', file.file)
      // this.imgPreview(file.file)
      const url = window.g.WEBAPI_HOST_URL + _this.uploadUrl + '?side=' + side
      axios
        .post(url, formData, {
          headers: this.headers
        })
        .then((res) => {
          toast.clear()
          if (res.code === 200) {
            debugger
            // this.item.value = res.data
            console.log(res.data)
            if (file instanceof Array) {
              // 判断是否是数组
              file.map((v, i) => {
                v.status = 'success'
                v.message = ''
                v.url = res.data
                if (side === 0) {
                  _this.faceSide = window.g.WEBAPI_HOST_URL + _this.viewUrl + '/' + res.data.faceImg
                  res.data.faceImg = _this.faceSide
                } else {
                  _this.backSide = window.g.WEBAPI_HOST_URL + _this.viewUrl + '/' + res.data.backImg
                  res.data.backImg = _this.backSide
                }
                _this.IdCardProcess(side, res.data)
              })
            } else {
              file.status = 'success'
              file.message = ''
              file.url = res.data
              if (side === 0) {
                _this.faceSide = window.g.WEBAPI_HOST_URL + _this.viewUrl + '/' + res.data.faceImg
                res.data.faceImg = _this.faceSide
              } else {
                _this.backSide = window.g.WEBAPI_HOST_URL + _this.viewUrl + '/' + res.data.backImg
                res.data.backImg = _this.backSide
              }
              this.IdCardProcess(side, res.data)
            }
          }
        })
        .catch(() => {
          toast.clear()
          this.$notify({
            type: 'warning',
            message: '图像识别失败！'
          })
        })
    },
    IdCardProcess(side, mData) {
      for (var key in mData) {
        this.idCardData[key] = mData[key]
      }
    },
    /**
     * 压缩图片
     */
    compressImages (res) {
      var defaultImage = {
        width: 210,
        height: 210,
        quality: 0.8, // 压缩图片的质量
        orientation: '' // 获取照片方向角属性，用户旋转控制
      }
      var img = new Image()
      img.src = res
      // let initSize = img.src.length
      img.onload = () => {
        console.log('压缩之前宽度： ' + img.width)
        console.log('压缩之前高度： ' + img.height)
        var canvas = document.createElement('canvas')
        var ctx = canvas.getContext('2d')
        if (img.width > defaultImage.width) {
          img.height = img.height * (defaultImage.width / img.width)
          img.width = defaultImage.width
        }
        if (img.height > defaultImage.height) {
          img.width *= defaultImage.height / img.height
          img.height = defaultImage.height
        }
        canvas.width = img.width
        canvas.height = img.height
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        EXIF.getData(this.file, () => { // IMG_FILE为图像数据
          // 是否是iPhone手机，iPhone 拍照之后的压缩是逆时针旋转90，针对iphone做一下处理
          if (navigator.userAgent.match(/iphone/i)) {
            defaultImage.orientation = EXIF.getTag(this.file, 'Orientation')
            // translate是平移变换，scale(-1,1)是向左翻转，rotate是顺时针旋转。
            // defaultImage.orientation = 6   // 测试iPhone手机
            // alert('Orientation:' + defaultImage.orientation) // 拍照方向
            switch (Number(defaultImage.orientation)) {
              case 2:
                ctx.translate(img.width, 0)
                ctx.scale(-1, 1)
                ctx.drawImage(img, 0, 0, img.width, img.height)
                break
              case 3:
                ctx.rotate(180 * Math.PI / 180)
                ctx.drawImage(img, -img.width, -img.height, img.width, img.height)
                break
              case 4:
                ctx.translate(img.width, 0)
                ctx.scale(-1, 1)
                ctx.rotate(180 * Math.PI / 180)
                ctx.drawImage(img, -img.width, -img.height, img.width, img.height)
                break
              case 5:
                ctx.translate(img.width, 0)
                ctx.scale(-1, 1)
                ctx.rotate(90 * Math.PI / 180)
                ctx.drawImage(img, 0, -img.width, img.height, img.width)
                break
              case 6:
                canvas.width = img.height
                canvas.height = img.width
                ctx.rotate(90 * Math.PI / 180)
                ctx.drawImage(img, 0, 0, img.width, -img.height)
                break
              case 7:
                ctx.translate(img.width, 0)
                ctx.scale(-1, 1)
                ctx.rotate(270 * Math.PI / 180)
                ctx.drawImage(img, -img.height, 0, img.height, img.width)
                break
              case 8:
                ctx.rotate(270 * Math.PI / 180)
                ctx.drawImage(img, -img.height, 0, img.height, img.width)
                break
              default:
                ctx.drawImage(img, 0, 0, img.width, img.height)
            }
          } else {
            ctx.drawImage(img, 0, 0, img.width, img.height)
          }
          var imgUrl = canvas.toDataURL('image/jpeg', defaultImage.quality)
          // 压缩之后的base64 图片地址
          this.faceSide = imgUrl
        })
      }
    },
    fileobj_change (inFile) {
      debugger
      // var _this = this
      // _this.show_loading = true
      var orientation = 0
      EXIF.getData(inFile.file, function() {
        EXIF.getAllTags(this)
        orientation = EXIF.getTag(this, 'Orientation')
      })
      console.log(orientation)
      var reader = new FileReader()
      reader.onload = function(readerEvent) {
        // var face_image = inFile.content // new Image()
        /* face_image.onload = function(imageEvent) {
          // 旋转图片
          // vue_this.faceSide = vue_this.rotateImage(face_image)
          debugger
          var canvas = document.createElement('canvas')
          _this.drawPhotoImage(this, canvas, face_image, orientation)
          _this.faceSide = canvas.toDataURL('image/jpeg')
          // _this.show_upload_next_button = true
          // _this.show_loading = false
        } */
        // face_image.src = readerEvent.target.result
      }
      reader.readAsDataURL(inFile.file)
    },
    drawPhotoImage(image, canvas, face_image, orientation) {
      var $this = this
      debugger
      // var max_size = 544
      var width = face_image.width
      var height = face_image.height

      // alert('width=' + width + ' / height=' + height)
      /*
      if (width > height) {
        if (width > max_size) {
          height *= max_size / width
          width = max_size
        }
      } else {
        if (height > max_size) {
          width *= max_size / height
          height = max_size
        }
      }
      */
      canvas.width = width
      canvas.height = height
      // alert(navigator.userAgent)
      if (navigator.userAgent.match(/iphone/i)) {
        // alert(orientation)
        if (orientation !== '' && orientation !== 1) {
          switch (orientation) {
            case 6:
              $this.rotateImg(image, 'left', canvas, width, height)
              break
            case 8:
              $this.rotateImg(image, 'right', canvas, width, height)
              break
            case 3:
              /*
              //原资料中旋转180度方法为调用两遍90度 但是我这边不起作用 所以增加一种新的方式 => right2
              rotateImg(image, 'right', canvas, width, height)
              rotateImg(image, 'right', canvas, width, height)*/
              $this.rotateImg(image, 'right2', canvas, width, height)
              break
            default:
              canvas.getContext('2d').drawImage(face_image, 0, 0, width, height)
              break
          }
        } else {
          canvas.getContext('2d').drawImage(face_image, 0, 0, width, height)
        }
      } else if ($this.get_ua_info()) {
        $this.rotateImg(image, 'left', canvas, width, height)
      } else {
        canvas.getContext('2d').drawImage(face_image, 0, 0, width, height)
      }
    },
    rotateImg(img, direction, canvas, width, height) {
      var min_step = 0
      var max_step = 3
      if (img == null) {
        return
      }
      var step = 2
      if (step == null) {
        step = min_step
      }
      if (direction === 'right') {
        step++
        step > max_step && (step = min_step)
      } else if (direction === 'right2') {
        step = 2
      } else {
        step--
        step < min_step && (step = max_step)
      }
      // 旋转角度以弧度值为参数
      var degree = (step * 90 * Math.PI) / 180
      var ctx = canvas.getContext('2d')
      // alert('step=>' + step + ' / degree=>' + degree)
      switch (step) {
        case 0:
          canvas.width = width
          canvas.height = height
          ctx.drawImage(img, 0, 0)
          break
        case 1:
          canvas.width = height
          canvas.height = width
          ctx.rotate(degree)
          ctx.drawImage(img, 0, -height)
          break
        case 2:
          canvas.width = width
          canvas.height = height
          ctx.rotate(degree)
          ctx.drawImage(img, -width, -height)
          break
        case 3:
          canvas.width = height
          canvas.height = width
          ctx.rotate(degree)
          ctx.drawImage(img, -width, 0)
          break
      }
      /* switch (step) {
        case 0:
          canvas.width = width
          canvas.height = height
          ctx.drawImage(img, 0, 0, width, height)
          break
        case 1:
          canvas.width = height
          canvas.height = width
          ctx.rotate(degree)
          ctx.drawImage(img, 0, -height, width, height)
          break
        case 2:
          canvas.width = width
          canvas.height = height
          ctx.rotate(degree)
          ctx.drawImage(img, -width, -height, width, height)
          break
        case 3:
          canvas.width = height
          canvas.height = width
          ctx.rotate(degree)
          ctx.drawImage(img, -width, 0, width, height)
          break
      } */
    },
    /**
     * 旋转图片
     * @param image         HTMLImageElement
     * @returns newImage    HTMLImageElement
     */
    rotateImage(image) {
      console.log('rotateImage')

      var width = image.width
      var height = image.height

      var canvas = document.createElement('canvas')
      var ctx = canvas.getContext('2d')

      var newImage = new Image()

      // 旋转图片操作
      EXIF.getData(image, function () {
        var orientation = EXIF.getTag(this, 'Orientation')
        // orientation = 6;//测试数据
        // alert('Orientation==>' + orientation)
        console.log('orientation:' + orientation)
        switch (orientation) {
          // 正常状态
          case 1:
            console.log('旋转0°')
            // canvas.height = height;
            // canvas.width = width;
            newImage = image
            break
          // 旋转90度
          case 6:
            console.log('旋转90°')
            canvas.height = width
            canvas.width = height
            ctx.rotate(Math.PI / 2)
            ctx.translate(0, -height)

            ctx.drawImage(image, 0, 0)
            newImage = canvas.toDataURL('Image/jpeg', 1)
            break
          // 旋转180°
          case 3:
            console.log('旋转180°')
            canvas.height = height
            canvas.width = width
            ctx.rotate(Math.PI)
            ctx.translate(-width, -height)

            ctx.drawImage(image, 0, 0)
            newImage = canvas.toDataURL('Image/jpeg', 1)
            break
          // 旋转270°
          case 8:
            console.log('旋转270°')
            canvas.height = width
            canvas.width = height
            ctx.rotate(-Math.PI / 2)
            ctx.translate(-height, 0)

            ctx.drawImage(image, 0, 0)
            newImage = canvas.toDataURL('Image/jpeg', 1)
            break
          // undefined时不旋转
          case undefined:
            console.log('undefined  不旋转')
            newImage = image
            break
        }
      })
      return newImage
    },
    // 判断是否为三星手机
    // 注：此方法准确率欠佳 若有需求可参考https://github.com/fex-team/ua-device
    get_ua_info() {
      if (navigator.userAgent.indexOf(' SM-') !== -1) {
        return true
      } else {
        return false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
  p {
    font-size: 12px;
    padding:4px;
  }
  .app-container {
    background: #F7F7F8
  }
  .container:first {
    margin-top: 10px;
    padding: 10px 0px;
  }
  .container {
    margin-top: 5px;
    background-color: #fff;
  }
  .van-popup {
    background: #F7F7F8
  }
  .van-row {
    padding: 10px 0;
  }
  .van-uploader div {
    width: 100%;
  }
  .van-uploader div div {
    width: 100%;
  }
</style>
